﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using System.Net;
using System.Net.Sockets;
using System.Threading;


namespace MonCorLib.Net.Service
{
    public class ServerSocketService : INetServerServiceable
    {
        public int port { get; private set; }
        public int backlog { get; private set; }

        private Socket server;
        private Thread acceptThread;
        private Dictionary<string, Socket> clientDic;

        public event EventHandler<ClientEventArgs> ConnectedClientEvent;
        public event EventHandler<ClientEventArgs> DisconnectedClientEvent;


        public ServerSocketService()
        {
            port = 7777;
            backlog = 20;
        }


        public void start()
        {
            Console.WriteLine("{0} starting...", this.ToString());

            clientDic = new Dictionary<string, Socket>();

            acceptThread = new Thread(new System.Threading.ThreadStart(acceptClient));
            acceptThread.IsBackground = true;
            acceptThread.Start();
        }

        private void acceptClient()
        {
            if (server == null)
                server = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

            server.Bind(new IPEndPoint(IPAddress.Parse("192.168.0.6"), port));
            server.Listen(backlog);

            Console.WriteLine("{0} listening...", this.ToString());
            while (true)
            {
                Socket client = server.Accept();
                
                if (client.Connected == true)
                {
                    IPEndPoint ip = client.RemoteEndPoint as IPEndPoint;
                    Console.WriteLine("접속 {0}[{1}]", ip.Address.ToString(), ip.Port.ToString());

                    clientDic.Add(ip.Address.ToString(), client);

                    if (ConnectedClientEvent != null)
                        ConnectedClientEvent(this, new ClientEventArgs(ip.Address.ToString()));
                }
            }
        }

        public void stop()
        {
            if (acceptThread.IsAlive == true)
                acceptThread.Abort();

            if (server.Connected == true)
                server.Shutdown(SocketShutdown.Both);

            clientDic.Clear();
            server.Close();

            Console.WriteLine("{0} closed...", this.ToString());
        }

        public void send(string message)
        {
            throw new NotImplementedException();
        }

        public string receive()
        {
            throw new NotImplementedException();
        }
    }
}